package go2

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"strings"
	"sync"

	"go2/pool"
)

// 优化的FileReadAll，使用缓冲读取和内存池
func FileReadAll(fileName string) []byte {
	if fileName == "" {
		return nil
	}

	// 获取文件信息先检查大小
	fileInfo, err := os.Stat(fileName)
	if err != nil {
		return nil
	}

	// 如果文件过大，使用流式读取
	if fileInfo.Size() > 10*1024*1024 { // 10MB
		return readLargeFile(fileName)
	}

	fileHandle, err := os.Open(fileName)
	if err != nil {
		return nil
	}
	defer fileHandle.Close()

	// 使用缓冲读取
	buf := pool.Malloc(int(fileInfo.Size()))
	defer pool.Free(buf)

	_, err = io.ReadFull(fileHandle, buf)
	if err != nil {
		return nil
	}

	return buf
}

// 读取大文件的优化版本
func readLargeFile(fileName string) []byte {
	fileHandle, err := os.Open(fileName)
	if err != nil {
		return nil
	}
	defer fileHandle.Close()

	// 使用带缓冲的读取器
	reader := bufio.NewReader(fileHandle)
	buffer := bytes.Buffer{}

	// 使用固定大小的缓冲块
	buf := pool.Malloc(32 * 1024) // 32KB缓冲块
	defer pool.Free(buf)

	for {
		n, err := reader.Read(buf)
		if n > 0 {
			buffer.Write(buf[:n])
		}
		if err != nil {
			if err == io.EOF {
				break
			}
			return nil
		}
	}

	return buffer.Bytes()
}

// 优化的FileAppend，使用缓冲写入
func FileAppend(fileName string, fileBytes []byte) bool {
	if fileName == "" {
		return false
	}

	if len(fileBytes) == 0 {
		return false
	}

	fileHandle, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0660)
	if err != nil {
		return false
	}
	defer fileHandle.Close()

	// 使用缓冲写入提高性能
	writer := bufio.NewWriterSize(fileHandle, 8*1024) // 8KB缓冲
	if _, err = writer.Write(fileBytes); err != nil {
		return false
	}

	// 确保所有数据都写入文件
	if err = writer.Flush(); err != nil {
		return false
	}

	return true
}

// 优化的FileExistHasPrefix，增加并发搜索功能
func FileExistHasPrefix(path, value string) bool {
	return FileExistHasPrefixConcurrent(path, value, 4)
}

// 并发版本的前缀搜索
func FileExistHasPrefixConcurrent(path, value string, concurrency int) bool {
	if concurrency <= 1 {
		return FileExistHasPrefixSync(path, value)
	}

	files, err := os.ReadDir(path)
	if err != nil {
		return false
	}

	// 使用通道来接收结果
	resultChan := make(chan bool, len(files))
	var wg sync.WaitGroup

	// 处理每个文件/目录
	for _, file := range files {
		wg.Add(1)
		go func(f os.DirEntry) {
			defer wg.Done()

			if f.IsDir() {
				resultChan <- FileExistHasPrefixConcurrent(path+"/"+f.Name(), value, concurrency)
			} else {
				resultChan <- strings.HasPrefix(f.Name(), value)
			}
		}(file)
	}

	// 等待所有goroutine完成
	go func() {
		wg.Wait()
		close(resultChan)
	}()

	// 检查结果
	for result := range resultChan {
		if result {
			return true
		}
	}

	return false
}

// 同步版本的递归搜索
func FileExistHasPrefixSync(path, value string) bool {
	files, err := os.ReadDir(path)
	if err != nil {
		return false
	}

	for _, file := range files {
		if file.IsDir() {
			if FileExistHasPrefixSync(path+"/"+file.Name(), value) {
				return true
			}
		} else {
			if strings.HasPrefix(file.Name(), value) {
				return true
			}
		}
	}

	return false
}

// 优化的FileCopy，使用缓冲和并行复制
func FileCopy(src, dst string) (int64, error) {
	sourceFileStat, err := os.Stat(src)
	if err != nil {
		return 0, err
	}

	if !sourceFileStat.Mode().IsRegular() {
		return 0, fmt.Errorf("%s is not a regular file", src)
	}

	// 对于大文件，使用并行复制
	if sourceFileStat.Size() > 10*1024*1024 { // 10MB
		return copyLargeFile(src, dst)
	}

	// 小文件使用标准复制
	return copySmallFile(src, dst)
}

// 小文件复制
func copySmallFile(src, dst string) (int64, error) {
	source, err := os.Open(src)
	if err != nil {
		return 0, err
	}
	defer source.Close()

	destination, err := os.Create(dst)
	if err != nil {
		return 0, err
	}
	defer destination.Close()

	// 使用缓冲复制
	buf := pool.Malloc(64 * 1024) // 64KB缓冲
	defer pool.Free(buf)

	bufReader := bufio.NewReader(source)
	bufWriter := bufio.NewWriter(destination)
	defer bufWriter.Flush()

	return io.CopyBuffer(bufWriter, bufReader, buf)
}

// 大文件并行复制
func copyLargeFile(src, dst string) (int64, error) {
	source, err := os.Open(src)
	if err != nil {
		return 0, err
	}
	defer source.Close()

	fileSize, err := source.Seek(0, io.SeekEnd)
	if err != nil {
		return 0, err
	}

	// 创建目标文件
	destination, err := os.Create(dst)
	if err != nil {
		return 0, err
	}
	defer destination.Close()

	// 预分配文件空间
	if err := destination.Truncate(fileSize); err != nil {
		return 0, err
	}

	// 使用4个goroutine并行复制
	const chunkSize = 4 * 1024 * 1024 // 4MB chunks
	const workers = 4

	var wg sync.WaitGroup
	errChan := make(chan error, workers)

	chunks := (fileSize + chunkSize - 1) / chunkSize
	for i := int64(0); i < chunks; i++ {
		wg.Add(1)
		go func(chunk int64) {
			defer wg.Done()

			start := chunk * chunkSize
			end := start + chunkSize
			if end > fileSize {
				end = fileSize
			}

			if err := copyChunk(source, destination, start, end-start); err != nil {
				errChan <- err
			}
		}(i)
	}

	// 等待所有goroutine完成
	go func() {
		wg.Wait()
		close(errChan)
	}()

	// 检查错误
	for err := range errChan {
		if err != nil {
			return 0, err
		}
	}

	return fileSize, nil
}

// 复制文件块
func copyChunk(src *os.File, dst *os.File, offset, size int64) error {
	buf := pool.Malloc(64 * 1024) // 64KB缓冲
	defer pool.Free(buf)

	srcReader := bufio.NewReaderSize(src, len(buf))
	dstWriter := bufio.NewWriterSize(dst, len(buf))
	defer dstWriter.Flush()

	// 定位到正确的位置
	if _, err := src.Seek(offset, io.SeekStart); err != nil {
		return err
	}
	if _, err := dst.Seek(offset, io.SeekStart); err != nil {
		return err
	}

	remaining := size
	for remaining > 0 {
		chunk := remaining
		if chunk > int64(len(buf)) {
			chunk = int64(len(buf))
		}

		_, err := io.CopyN(dstWriter, srcReader, chunk)
		if err != nil {
			return err
		}

		remaining -= chunk
	}

	return nil
}
